# 格式化业绩
import json, requests, re
import sys
#数据库查询
import pymysql
from zentao.settings import PYMYSQL_CONF
import base64
from bid.ai_generate.get_project import get_project

#大模型提取业绩条件关键信息
def dify_chat_streaming(query):
    #找表
    # API端点和API密钥
    # url = 'http://172.16.32.45:11206/v1/chat-messages' #v1/chat-messages'调用聊天框  workflows/run智能体
    url = f'http://172.17.0.1:8083/v1/chat-messages' #v1/chat-messages'调用聊天框  workflows/run智能体
    api_key = 'app-VZMCyTB405qEow9fvR927Gf6'  # 工作流查表

    # 请求头
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }

    # 请求数据
    data = {
        "inputs": {},
        "query": query,
        "response_mode": "streaming", #blocking streaming
        "conversation_id": "",
        "user": "abc-123",
            }

    # 将数据转换为JSON字符串
    data_json = json.dumps(data)

    # 发送POST请求
    # response = requests.post(url, headers=headers, data=data_json.encode("utf-8"))
    # response.encoding = 'utf-8'

    answer = ''
    # 发送GET请求，并设置stream=True
    with requests.post(url, headers=headers, data=data_json.encode("utf-8"), stream=True) as r:
        # 检查请求是否成功
        r.raise_for_status()

        # 打印每一行文本
        for line in r.iter_lines():
            # 忽略保持连接的空行
            if line:
                # 解码每一行，因为返回的数据可能是字节串
                line = line.decode('utf-8')
                # print(line)
                if 'data: ' in line:
                    data = json.loads(line.replace('data: ', ''))
                    if data['event'] == 'message':
                        # print(data['answer'])
                        answer = data['answer']
                        yield answer
                    elif data['event'] == 'message_end':
                        return ''
                        # sys.stdout.write(f"\r{str([answer])}")
                        # sys.stdout.flush()
    # return answer

#按相似程度排序
def calculate_similarity(item, tt, bt, tk):
    # techType相似度，因为techType是字符串，直接判断是否在筛选条件中
    tt_similarity = 1 if item[2] in tt else 0
    # 计算businessType相似度
    bt_similarity = len(set(item[3].split(',')).intersection(bt))
    # 计算techKeywords相似度
    tk_similarity = len(set(item[-3].split(',')).intersection(tk))

    return (tt_similarity, bt_similarity, tk_similarity,item[-1])

#文本基于url的base64编码(+替换成-，/替换成_，=替换成.)
def url_bs64_encode(string):
    bs64_str = str(base64.b64encode(string.encode("utf-8")), "utf-8")
    return  bs64_str.replace('+','-').replace('/','_').replace('=','.')

def extract_project_info(text, task_id, conversation_id):

    # text = '''
    # 项目名称：标包4：客户服务平台（南方区域统一电力交易平台V2.1市场管理、现货结算等优化）建设项目
    # 业绩要求：投标人2021年至投标截止日具有咨询评审或信息化技术服务相关业绩，须提供合同（首页、服务内 容页、盖章签字页扫描件）和验收报告、论文、专 利、获奖等任意一种验收证明材料
    # 业绩评分标准：按照近年(2021年至今)完成的同类项目业绩金额进行计分：每三百万2分，最高得10分。 注：提供合同（首页、服务内容页、盖章签字页扫描件）和验收报告、论文、专利、获奖等任意一种验收证明材料，否则相关业绩不得分。
    # 帮我筛选肖建毅的业绩
    # '''

    #流式接受数据
    stream_content = dify_chat_streaming(text)
    answer = ''
    try:
        while True:
            mid_answer = next(stream_content)
            answer+=mid_answer
            yield f'{task_id}\t{conversation_id}\t{mid_answer}'
            # sys.stdout.write(f"\r {str([answer])}")
            # sys.stdout.flush()
    except:
        pass

    #获取返回的json
    pattern = r"```json(.*?)```"
    matches = re.findall(pattern, answer, re.DOTALL)
    if len(matches) != 0:
        llm_data = json.loads(matches[-1])
        # print('\n')
        print(llm_data)
    else:
        # return '', []
        yield f'{task_id}\t{conversation_id}\t\n未找到相关业绩'
        return

    if len(llm_data['业务类型'] + llm_data['技术类型']) == 0:
        # return '', []
        yield f'{task_id}\t{conversation_id}\t\n未找到相关业绩'
        return

    # 返回文件生成中
    if llm_data['负责人']:
        yield f'{task_id}\t{conversation_id}\t\n负责人业绩文件生成中...'
    else:
        yield f'{task_id}\t{conversation_id}\t\n公司业绩文件生成中...'


        #数据库查询
    connect = pymysql.connect(**PYMYSQL_CONF)
    sql = '''select p.id,p.name,p.techType,p.businessType,p.techKeywords,p.contractSignDate,p.contractAmount 
    from ex_project p 
    left join ex_team t on p.PM=t.account
    '''

    #获取与或条件
    or_sql = []
    and_sql = []
    for key in llm_data.keys():
        if key == '业务类型':
            if len(llm_data[key]) != 0:
                for i in llm_data[key]:
                    or_sql.append(f"p.businessType like '%{i}%'")
        elif key == '技术类型':
            if len(llm_data[key]) != 0:
                for i in llm_data[key]:
                    or_sql.append(f"p.techType like '%{i}%'")
        elif key == '起始年份':
            if llm_data[key].isdigit():
                and_sql.append(f"p.contractSignDate>='{llm_data[key]}-1-1'")
        elif key == '截止年份':
            if llm_data[key].isdigit():
                and_sql.append(f"p.contractSignDate>='{llm_data[key]}-1-1'")
        elif key == '负责人':
            if llm_data[key] and llm_data[key] != '张三三':
                and_sql.append(f"t.name='{llm_data[key]}'")

    #拼接sql
    if or_sql:
        sql += f"where ({' or '.join(or_sql)})"

    if and_sql:
        if 'where' in sql:
            sql += f" and ({' and '.join(and_sql)})"
        else:
            sql += f"where {'and '.join(or_sql)}"

    cursor = connect.cursor()
    cursor.execute(sql)
    sql_data = cursor.fetchall()
    # columns = [i[0] for i in cursor.description]
    cursor.close()
    connect.close()

    # 根据相似度排序
    sorted_data = sorted(sql_data, key=lambda x: calculate_similarity(x, llm_data['技术类型'], llm_data['业务类型'], llm_data['关键词']), reverse=True)

    ids = []
    for item in sorted_data:
        ids.append(item[0])
        # print(
        #     f"{item}, \nSimilarity: {calculate_similarity(item, llm_data['技术类型'], llm_data['业务类型'], llm_data['关键词'])}\t"
        #     f"{llm_data['技术类型'], llm_data['业务类型'], llm_data['关键词']}\n==============================")
    if len(ids) == 0:
        yield f'{task_id}\t{conversation_id}\t\n未找到相关业绩'
        return

    # 生成文件
    if llm_data['负责人']:
        filename, save_path = get_project('pmProject', ids)
    else:
        filename, save_path = get_project('project', ids)

    # 返回下载链接
    download_url = f"/api/bid/get_file?path={url_bs64_encode(save_path)}"
    yield f'{task_id}\t{conversation_id}\t\n下载链接：<a href="{download_url}">{filename}</a>'

    # return llm_data['负责人'], ids

